package pathfind;

import data.NavmeshRegion;
import data.RegionConnection;
import java.util.List;

/**
 * Pathfinder that try to search path in regions graph
 */
public class GlobalPathFinder extends AStarAbstract<NavmeshRegion> {

    private final NavmeshRegion end;

    public GlobalPathFinder(NavmeshRegion end) {
        this.end = end;
    }

    @Override
    protected boolean isGoal(NavmeshRegion node) {
        return node == end;
    }

    @Override
    protected double g(NavmeshRegion from, NavmeshRegion to) {
        if (from == to) {
            return 0.0;
        }

        return length(from, to);
    }

    @Override
    protected double h(NavmeshRegion from, NavmeshRegion to) {
        return (double) Math.abs(from.getCenter().getX() - to.getCenter().getX()) + Math.abs(from.getCenter().getY() - to.getCenter().getY());

    }

    private double length(NavmeshRegion p1, NavmeshRegion p2) {
        double a = p1.getCenter().getX() - p2.getCenter().getX();
        a = a * a;
        double b = p1.getCenter().getY() - p2.getCenter().getY();
        b = b * b;
        return Math.sqrt(a + b);
    }

    @Override
    protected List<NavmeshRegion> generateSuccessors(NavmeshRegion node, List<NavmeshRegion> outlist) {
        if (node.getConnection() != null) {
            for (RegionConnection connection : node.getConnection().values()) {
                outlist.add(connection.getPolygon());
            }
        }

        return outlist;
    }

    @Override
    protected double squaredLengthToGoal(NavmeshRegion polygon) {
        double a = end.getCenter().getX() - polygon.getCenter().getX();
        a = a * a;
        double b = end.getCenter().getY() - polygon.getCenter().getY();
        b = b * b;
        return a + b;
    }

    @Override
    public AStarAbstract<NavmeshRegion> newInstance(NavmeshRegion end, Object additionalParam) {
        return new GlobalPathFinder(end);
    }
}